package com.link.serve.tcp.process;

import com.alibaba.fastjson2.JSON;
import com.link.serve.constants.LinkRedisKey;
import com.link.serve.downlink.messaging.ChatMessage;
import com.link.serve.tcp.linkdata.SingleUserChannelManager;
import com.link.serve.tcp.message.Message;
import com.link.serve.tcp.message.proto.PackData;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * 单个消息推送
 * @Author: 杰
 * @Project :link-server
 * @DateTime: 2025-01-25 19:02
 **/
@Component
@Slf4j
public class SingleMessagePushProcessor extends AbstractMessageProcessor<Message> {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**GRPC中的下行请求推送对方的channel中
     * @param msg 消息对象 */
    @Override
    public void process(Message msg) {
        PackData.Body body = msg.getBody();
        try {
            // 使用 FastJSON 将 JSON 转换为 ChatMessage 实例
            ChatMessage chatMessage = JSON.parseObject(body.getData(), ChatMessage.class);
            log.info("解析后的消息内容：{}", chatMessage);

            //虎丘
            long receiverId = chatMessage.getReceiverId();
            long senderId = chatMessage.getSenderId();
            log.info("准备推送消息，发送方：{}，接收方：{}", senderId, receiverId);

            // 判断对方是否在线
            String key = String.join(":", LinkRedisKey.LINK_USER_SERVER_ID, String.valueOf(receiverId));
            if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
                if (SingleUserChannelManager.isOnline(senderId)) {
                    // 在本机，直接推送
                    log.info("接收方 {} 在本机，直接推送消息。", receiverId);
                    SingleUserChannelManager.getChannel(receiverId).writeAndFlush(msg);
                } else {
                    // 不在本机，转发到对应服务器
                    String serverId = (String) redisTemplate.opsForValue().get(key);
                    log.info("接收方 {} 不在本机，转发到服务器 {}", receiverId, serverId);
                    forwardMessageToServer(serverId, body);
                }
            } else {
                log.info("接收方 {} 不在线，无法推送消息。", receiverId);
            }
        } catch (Exception e) {
            log.error("消息解析或处理失败：{}", e.getMessage(), e);
        }
    }

    @Override
    public void process(ChannelHandlerContext ctx, Message msg) {
        process(msg);
    }

    /**
     * 转发消息到指定服务器
     * @param serverId 目标服务器ID
     * @param body 消息体
     */
    private void forwardMessageToServer(String serverId, PackData.Body body) {
        // 这里可以去找到看是在哪个集群机器里面然后发过去即可
        log.info("转发消息到服务器 {}，消息内容：{}", serverId, body);

    }
}
